package com.thp.proxy.cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class Witchcraft implements MethodInterceptor {

	
	
	/**
	 * 疑问?
	 * 好像并没有持有被代理对象的引用
	 * cgli的代理不需要自己传引用
	 * 这个引用是由cglib自己new出来的
	 * @param obj
	 * @return
	 * @throws Exception
	 */
	public Object getInstance(Class clazz) throws Exception {

		Enhancer enhancer = new Enhancer();
		
		// 把父类设置为谁?
		
		// 这一步就是告诉cglib生成的子类需要继承哪个类
		enhancer.setSuperclass(clazz);
		
		// 设置回调
		enhancer.setCallback(this);  // this才有增强的方法   到时就需要操作把this添加到生成的代理对象中
		
		
		// 第一步:生成源代码  
		// 第二步:编译成class文件   
		// 第三步:加载到JVM中,并且=返回被代理对象
		return enhancer.create();
		
	}
	
	/**
	 * 同样是做了字节码重组这样一件事
	 * 对于用户来说的无感知的
	 */
	@Override
	public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		
		// 这个obj 就是子类的引用
		
		
		System.out.println("-------------------");
		// 调用的是invokeSuper() 方法
		// 如果调用invoke()方法是会出现死循环的
		// methodProxy.invoke(obj, args);
		// 这个obj的引用是由cglib给我们new出来的
		// cglib  new 出来以后的对象时被代理对象的子类(继承了自己写的那个类)
		// OOP里面的规范 : 在new 子类之前实际上市默认调用了super()方法的,也就是说new 子类的同时也必须先new出父类
		// 这就相当于是间接地持有父类的引用
		// 子类重写了父类的所有的方法
		// 我们改变了子类对象的默写属性是可以间接地操作到父类的属性的
		
		methodProxy.invokeSuper(obj, args);
		System.out.println("-------------------");
		return null;
	}
	
}
